using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using System.Text.Json;
using CKY.AgentPlatform.Application.Contracts.McpTools;
using CKY.AgentPlatform.Domain.McpTools;
using CKY.AgentPlatform.Common.Types;
using McpTool = CKY.AgentPlatform.Domain.McpTools.McpTool;
using McpToolExecutionResult = CKY.AgentPlatform.Common.Types.McpToolExecutionResult;
using McpToolExecutionInput = CKY.AgentPlatform.Domain.McpTools.McpToolExecutionInput;

namespace CKY.AgentPlatform.Services
{
    /// <summary>
    /// MCP工具执行服务 - 负责调用MCP协议的工具
    /// </summary>
    public partial class McpToolExecutionService : ApplicationService, IMcpToolExecutionService
    {
        private readonly IRepository<McpTool, Guid> _mcpToolRepository;
        private readonly ILogger<McpToolExecutionService> _logger;
        private readonly IMcpClientManager _mcpClientManager;
        private readonly IServiceProvider _serviceProvider;

        public McpToolExecutionService(
            IRepository<McpTool, Guid> mcpToolRepository,
            ILogger<McpToolExecutionService> logger,
            IMcpClientManager mcpClientManager,
            IServiceProvider serviceProvider)
        {
            _mcpToolRepository = mcpToolRepository;
            _logger = logger;
            _mcpClientManager = mcpClientManager;
            _serviceProvider = serviceProvider;
        }

        /// <summary>
        /// 执行MCP工具调用
        /// </summary>
        /// <param name="input">工具执行输入</param>
        /// <returns>工具执行结果</returns>
        public async Task<McpToolExecutionResult> ExecuteToolAsync(McpToolExecutionInput input)
        {
            var executionId = Guid.NewGuid();
            _logger.LogInformation("开始执行MCP工具调用: {ToolName}, 执行ID: {ExecutionId}",
                input.ToolName, executionId);

            try
            {
                // 获取工具配置
                var toolConfig = await GetToolConfigAsync(input.ToolName);
                if (toolConfig == null)
                {
                    throw new InvalidOperationException($"未找到工具配置: {input.ToolName}");
                }

                // 验证工具参数
                ValidateToolParameters(toolConfig, input.Parameters);

                // 根据工具类型执行不同的调用逻辑
                var result = toolConfig.ToolType switch
                {
                    McpToolType.Resource => await ExecuteMcpServerToolAsync(toolConfig, input, executionId),
                    McpToolType.CodeExecution => await ExecuteLocalFunctionToolAsync(toolConfig, input, executionId),
                    McpToolType.Http => await ExecuteHttpApiToolAsync(toolConfig, input, executionId),
                    McpToolType.Custom => await ExecuteScriptToolAsync(toolConfig, input, executionId),
                    _ => throw new NotSupportedException($"不支持的工具类型: {toolConfig.ToolType}")
                };

                _logger.LogInformation("MCP工具调用完成: {ToolName}, 执行ID: {ExecutionId}, 成功: {Success}",
                    input.ToolName, executionId, result.Success);

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "MCP工具调用异常: {ToolName}, 执行ID: {ExecutionId}",
                    input.ToolName, executionId);

                return new McpToolExecutionResult
                {
                    Success = false,
                    ErrorMessage = ex.Message
                };
            }
        }

        /// <summary>
        /// 执行MCP服务器工具
        /// </summary>
        private async Task<McpToolExecutionResult> ExecuteMcpServerToolAsync(McpTool toolConfig, McpToolExecutionInput input, Guid executionId)
        {
            try
            {
                // 简化MCP工具执行 - 直接调用管理器
                // Note: Domain IMcpClientManager doesn't have GetOrCreateClientAsync method

                // 构建工具调用请求
                var toolRequest = new McpToolRequest
                {
                    Method = $"tools/call/{input.ToolName}",
                    Params = new Dictionary<string, object>
                    {
                        { "name", input.ToolName },
                        { "arguments", input.Parameters ?? new Dictionary<string, object>() }
                    }
                };

                // 发送工具调用请求
                var timeout = TimeSpan.FromMilliseconds(input.Timeout);
                var mcpClient = await _mcpClientManager.GetClientAsync(toolConfig.McpServerId.ToString());
                var response = await mcpClient.SendRequestAsync(toolRequest.Method, toolRequest.Params);

                // 处理响应
                if (response.Error != null)
                {
                    return new McpToolExecutionResult
                    {
                        Success = false,
                        ErrorMessage = $"MCP工具调用失败: {response.Error.Message}"
                    };
                }

                return new McpToolExecutionResult
                {
                    Success = true,
                    Result = response.Result
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "MCP服务器工具调用异常: {ToolName}, 执行ID: {ExecutionId}",
                    input.ToolName, executionId);
                return new McpToolExecutionResult
                {
                    Success = false,
                    ErrorMessage = ex.Message
                };
            }
        }

        /// <summary>
        /// 执行本地函数工具
        /// </summary>
        private async Task<McpToolExecutionResult> ExecuteLocalFunctionToolAsync(McpTool toolConfig, McpToolExecutionInput input, Guid executionId)
        {
            try
            {
                // 解析函数类型和名称
                var functionInfo = ParseFunctionInfo(toolConfig.FunctionName);
                if (functionInfo == null)
                {
                    throw new InvalidOperationException($"无效的函数配置: {toolConfig.FunctionName}");
                }

                // 通过反射动态调用函数
                var result = await InvokeFunctionAsync(functionInfo, input.Parameters);

                return new McpToolExecutionResult
                {
                    Success = true,
                    Result = result
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "本地函数工具调用异常: {ToolName}, 执行ID: {ExecutionId}",
                    input.ToolName, executionId);
                return new McpToolExecutionResult
                {
                    Success = false,
                    ErrorMessage = ex.Message
                };
            }
        }

        /// <summary>
        /// 执行HTTP API工具
        /// </summary>
        private async Task<McpToolExecutionResult> ExecuteHttpApiToolAsync(McpTool toolConfig, McpToolExecutionInput input, Guid executionId)
        {
            try
            {
                var httpClient = _serviceProvider.GetRequiredService<System.Net.Http.IHttpClientFactory>().CreateClient();

                // 构建请求URL
                var requestUrl = toolConfig.ApiEndpoint;
                if (input.Parameters != null)
                {
                    foreach (var param in input.Parameters)
                    {
                        requestUrl = requestUrl.Replace($"{{{param.Key}}}", param.Value?.ToString());
                    }
                }

                // 构建请求内容
                HttpContent requestContent = null;
                if (toolConfig.HttpMethod.ToUpper() == "POST" || toolConfig.HttpMethod.ToUpper() == "PUT")
                {
                    var jsonContent = JsonSerializer.Serialize(input.Parameters);
                    requestContent = new System.Net.Http.StringContent(jsonContent, System.Text.Encoding.UTF8, "application/json");
                }

                // 设置请求头
                if (!string.IsNullOrWhiteSpace(toolConfig.Headers))
                {
                    var headers = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(toolConfig.Headers);
                    if (headers != null)
                    {
                        foreach (var header in headers)
                        {
                            httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
                        }
                    }
                }

                // 发送HTTP请求
                var response = await httpClient.SendAsync(new System.Net.Http.HttpRequestMessage
                {
                    Method = new System.Net.Http.HttpMethod(toolConfig.HttpMethod),
                    RequestUri = new System.Uri(requestUrl),
                    Content = requestContent
                });

                // 处理响应
                var responseContent = await response.Content.ReadAsStringAsync();
                if (!response.IsSuccessStatusCode)
                {
                    return new McpToolExecutionResult
                    {
                        Success = false,
                        ErrorMessage = $"HTTP API调用失败: {response.StatusCode}, 响应: {responseContent}"
                    };
                }

                // 尝试解析JSON响应
                try
                {
                    var jsonResponse = JsonSerializer.Deserialize<JsonElement>(responseContent);
                    return new McpToolExecutionResult
                    {
                        Success = true,
                        Result = jsonResponse
                    };
                }
                catch
                {
                    // 如果不是JSON，直接返回字符串
                    return new McpToolExecutionResult
                    {
                        Success = true,
                        Result = responseContent
                    };
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "HTTP API工具调用异常: {ToolName}, 执行ID: {ExecutionId}",
                    input.ToolName, executionId);
                return new McpToolExecutionResult
                {
                    Success = false,
                    ErrorMessage = ex.Message
                };
            }
        }

        /// <summary>
        /// 执行脚本工具
        /// </summary>
        private async Task<McpToolExecutionResult> ExecuteScriptToolAsync(McpTool toolConfig, McpToolExecutionInput input, Guid executionId)
        {
            try
            {
                // 这里可以根据不同的脚本类型执行不同的逻辑
                // 例如：Python、JavaScript、PowerShell等
                var scriptType = toolConfig.ScriptType?.ToLower() ?? "javascript";

                var result = scriptType switch
                {
                    "javascript" => await ExecuteJavaScriptScriptAsync(toolConfig.ScriptContent, input.Parameters),
                    "python" => await ExecutePythonScriptAsync(toolConfig.ScriptContent, input.Parameters),
                    "powershell" => await ExecutePowerShellScriptAsync(toolConfig.ScriptContent, input.Parameters),
                    _ => throw new NotSupportedException($"不支持的脚本类型: {scriptType}")
                };

                return new McpToolExecutionResult
                {
                    Success = true,
                    Result = result
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "脚本工具调用异常: {ToolName}, 执行ID: {ExecutionId}",
                    input.ToolName, executionId);
                return new McpToolExecutionResult
                {
                    Success = false,
                    ErrorMessage = ex.Message
                };
            }
        }

        /// <summary>
        /// 执行JavaScript脚本
        /// </summary>
        private async Task<object> ExecuteJavaScriptScriptAsync(string scriptContent, Dictionary<string, object> parameters)
        {
            // 这里可以使用Jint或其他JavaScript引擎
            // 简化实现，直接返回模拟结果
            await Task.Delay(100); // 模拟执行时间

            return new
            {
                message = "JavaScript脚本执行完成",
                parameters = parameters,
                timestamp = DateTime.UtcNow
            };
        }

        /// <summary>
        /// 执行Python脚本
        /// </summary>
        private async Task<object> ExecutePythonScriptAsync(string scriptContent, Dictionary<string, object> parameters)
        {
            // 这里可以使用IronPython或调用Python进程
            // 简化实现，直接返回模拟结果
            await Task.Delay(200); // 模拟执行时间

            return new
            {
                message = "Python脚本执行完成",
                parameters = parameters,
                timestamp = DateTime.UtcNow
            };
        }

        /// <summary>
        /// 执行PowerShell脚本
        /// </summary>
        private async Task<object> ExecutePowerShellScriptAsync(string scriptContent, Dictionary<string, object> parameters)
        {
            // 这里可以使用PowerShell SDK
            // 简化实现，直接返回模拟结果
            await Task.Delay(150); // 模拟执行时间

            return new
            {
                message = "PowerShell脚本执行完成",
                parameters = parameters,
                timestamp = DateTime.UtcNow
            };
        }

        /// <summary>
        /// 获取工具配置
        /// </summary>
        private async Task<McpTool> GetToolConfigAsync(string toolName)
        {
            var tools = await _mcpToolRepository.GetListAsync();
            return tools.FirstOrDefault(t => t.Name == toolName && t.IsActive);
        }

        /// <summary>
        /// 验证工具参数
        /// </summary>
        private void ValidateToolParameters(McpTool toolConfig, Dictionary<string, object> parameters)
        {
            if (toolConfig.Parameters == null)
                return;

            try
            {
                var schema = JsonSerializer.Deserialize<JsonElement>(toolConfig.Parameters);
                var requiredProperties = schema.TryGetProperty("required", out var requiredElement)
                    ? requiredElement.EnumerateArray().Select(p => p.GetString()).ToList()
                    : new List<string>();

                // 检查必需参数
                foreach (var requiredParam in requiredProperties)
                {
                    if (!parameters.ContainsKey(requiredParam))
                    {
                        throw new ArgumentException($"缺少必需参数: {requiredParam}");
                    }
                }

                // TODO: 可以添加更详细的参数验证逻辑
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "参数验证失败: {ToolName}", toolConfig.Name);
            }
        }

        /// <summary>
        /// 解析函数信息
        /// </summary>
        private FunctionInfo ParseFunctionInfo(string functionName)
        {
            if (string.IsNullOrWhiteSpace(functionName))
                return null;

            var parts = functionName.Split('.');
            if (parts.Length != 2)
                return null;

            return new FunctionInfo
            {
                TypeName = parts[0],
                MethodName = parts[1]
            };
        }

        /// <summary>
        /// 通过反射调用函数
        /// </summary>
        private async Task<object> InvokeFunctionAsync(FunctionInfo functionInfo, Dictionary<string, object> parameters)
        {
            try
            {
                // 获取类型
                var type = Type.GetType(functionInfo.TypeName);
                if (type == null)
                {
                    // 尝试从当前程序集中获取
                    type = AppDomain.CurrentDomain.GetAssemblies()
                        .Select(a => a.GetType(functionInfo.TypeName))
                        .FirstOrDefault(t => t != null);
                }

                if (type == null)
                {
                    throw new TypeLoadException($"未找到类型: {functionInfo.TypeName}");
                }

                // 获取方法
                var method = type.GetMethod(functionInfo.MethodName);
                if (method == null)
                {
                    throw new MissingMethodException($"未找到方法: {functionInfo.MethodName}");
                }

                // 创建实例（如果是实例方法）
                object instance = null;
                if (!method.IsStatic)
                {
                    instance = Activator.CreateInstance(type);
                    if (instance == null)
                    {
                        throw new InvalidOperationException($"无法创建类型实例: {functionInfo.TypeName}");
                    }
                }

                // 准备参数
                var methodParams = method.GetParameters();
                var args = new object[methodParams.Length];

                for (int i = 0; i < methodParams.Length; i++)
                {
                    var paramName = methodParams[i].Name;
                    if (parameters.TryGetValue(paramName, out var paramValue))
                    {
                        args[i] = Convert.ChangeType(paramValue, methodParams[i].ParameterType);
                    }
                    else
                    {
                        args[i] = methodParams[i].DefaultValue;
                    }
                }

                // 调用方法
                var result = method.Invoke(instance, args);

                // 如果是异步方法，等待结果
                if (result is Task task)
                {
                    await task;
                    if (task.GetType().GetProperty("Result") != null)
                    {
                        result = task.GetType().GetProperty("Result").GetValue(task);
                    }
                    else
                    {
                        result = null;
                    }
                }

                return result;
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"函数调用失败: {functionInfo.TypeName}.{functionInfo.MethodName}", ex);
            }
        }

        #region IMcpToolExecutionService Implementation

        /// <summary>
        /// 执行MCP工具
        /// </summary>
        /// <param name="toolId">工具ID</param>
        /// <param name="input">执行输入</param>
        /// <returns>执行结果</returns>
        public async Task<object> ExecuteAsync(Guid toolId, McpToolExecutionInput input)
        {
            var tool = await _mcpToolRepository.GetAsync(toolId);
            if (tool == null)
            {
                throw new InvalidOperationException($"未找到工具: {toolId}");
            }

            // 使用工具名称执行
            input.ToolName = tool.Name;
            var result = await ExecuteToolAsync(input);

            return result.Result;
        }

        /// <summary>
        /// 批量执行MCP工具
        /// </summary>
        /// <param name="toolId">工具ID</param>
        /// <param name="inputs">执行输入列表</param>
        /// <returns>执行结果列表</returns>
        public async Task<object[]> BatchExecuteAsync(Guid toolId, McpToolExecutionInput[] inputs)
        {
            var tool = await _mcpToolRepository.GetAsync(toolId);
            if (tool == null)
            {
                throw new InvalidOperationException($"未找到工具: {toolId}");
            }

            var results = new List<object>();

            foreach (var input in inputs)
            {
                input.ToolName = tool.Name;
                var result = await ExecuteToolAsync(input);
                results.Add(result.Result);
            }

            return results.ToArray();
        }

        /// <summary>
        /// 获取工具执行状态
        /// </summary>
        /// <param name="executionId">执行ID</param>
        /// <returns>执行状态</returns>
        public async Task<McpToolExecutionStatus> GetExecutionStatusAsync(Guid executionId)
        {
            // 这里应该从存储中获取执行状态
            // 简化实现，返回默认状态
            await Task.CompletedTask;

            return new McpToolExecutionStatus
            {
                ExecutionId = executionId,
                Status = "Completed",
                Progress = 100,
                Result = new { message = "执行完成" },
                StartTime = DateTime.UtcNow.AddMinutes(-1),
                EndTime = DateTime.UtcNow
            };
        }

        /// <summary>
        /// 取消工具执行
        /// </summary>
        /// <param name="executionId">执行ID</param>
        /// <returns>是否成功</returns>
        public async Task<bool> CancelExecutionAsync(Guid executionId)
        {
            // 这里应该实现取消逻辑
            // 简化实现，直接返回true
            await Task.CompletedTask;

            _logger.LogInformation("取消工具执行: {ExecutionId}", executionId);
            return true;
        }

        #endregion
    }

    /// <summary>
    /// 函数信息
    /// </summary>
    public class FunctionInfo
    {
        public string TypeName { get; set; }
        public string MethodName { get; set; }
    }

    /// <summary>
    /// MCP工具请求
    /// </summary>
    public class McpToolRequest
    {
        public string Method { get; set; }
        public Dictionary<string, object> Params { get; set; }
    }
}